package com.atguigu.jinx.conf;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * 定义交换机与队列的Bean 并且使之绑定
 * 生产者 -> 普通交换机 -> 普通队列 -> 消费者1
 * |
 * -> 死信交换机 -> 死信队列 -> 消费者2
 * 需要两个交换机两个队列、三个路由键。两个普通之间我用了"test.#"
 * 普通与死信之间用了"test.dead.heHe" 两个死信之间用了"test.dead.#" 生产的消息用的就是"test.dead.heHe"
 */
@Component
public class RabbitMQConfig {

    public static final String EXCHANGE_NAME = "normal_exchange_name";
    public static final String QUEUE_NAME = "normal_queue_name";
    public static final String DEAD_EXCHANGE_NAME = "dead_exchange_name";
    public static final String DEAD_QUEUE_NAME = "dead_queue_name";
    public static final String DEAD_LETTER_ROUTING_KEY = "test.dead.heHe";

    /**
     * 存活时间(毫秒值)
     *
     */
//    private static final int TTL_TIME = 600000; 暂定十分钟  六十万毫秒->六百秒->十分钟
    private static final int TTL_TIME = 600000;

    /**
     * 普通交换机
     *
     * @return 生成普通交换机(通配符模式)
     */
    @Bean("normalExchange")
    public Exchange normalExchange() {
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
    }

    /**
     * 死信交换机
     *
     * @return 生成死信交换机(通配符模式)
     */
    @Bean("deadExchange")
    public Exchange deadExchange() {
        return ExchangeBuilder.topicExchange(DEAD_EXCHANGE_NAME).durable(true).build();
    }

    //普通队列绑定死信交换机并且带上路由键 为了实现死信消息于是配置队列TTL
    @Bean("normalQueue")
    public Queue normalQueue() {
        // 该代码的作用=>声明一个普通的消息队列,存活时间为十分钟,绑定死信交换机
        return QueueBuilder.durable(QUEUE_NAME).ttl(TTL_TIME).deadLetterExchange(DEAD_EXCHANGE_NAME)
                .deadLetterRoutingKey(DEAD_LETTER_ROUTING_KEY)
                .build();
    }

    // 声明死信队列 但是未绑定交换机
    @Bean("deadQueue")
    public Queue deadQueue() {
        return QueueBuilder.durable(DEAD_QUEUE_NAME).build();
    }

    /**
     * 绑定普通交换机和队列 使用通配符 只要是通配符为test.123 什么的都会路由到该通配符交换机中   监听该队列即可<=消费者
     *
     * @param exchange
     * @param queue
     * @return
     */
    @Bean
    public Binding link(@Qualifier("normalExchange") Exchange exchange,
                        @Qualifier("normalQueue") Queue queue) {
        return BindingBuilder.bind(queue).to(exchange).with("test.#").noargs();
    }

    /**
     * 绑定死信队列
     * 该通配符是
     *
     * @param exchange 死信交换机
     * @param queue    死信队列
     * @return 绑定结果
     */
    @Bean
    public Binding deadLink(@Qualifier("deadExchange") Exchange exchange,
                            @Qualifier("deadQueue") Queue queue) {
        return BindingBuilder.bind(queue).to(exchange).with("test.dead.heHe").noargs();
    }
}